<?php

namespace App\Models;

use App\Constant\JpushCode;
use App\Constant\QueueKey;
use App\Constant\SmsTemplate;
use App\Constant\NewFlowEnum;
use App\Events\JpushNoticeEvent;
use App\Events\LoanRequestRetryEvent;
use App\Events\NewFlowOrderEvent;
use App\Facades\MoneyPlatformRequestFacade;
use App\Facades\SamLogFacade;
use App\Jobs\LoanRequestSuccessAfterSixJob;
use App\Jobs\LoanRequestSuccessAfterTwentyFourJob;
use App\Jobs\LoanRequestSuccessRestTwelveJob;
use App\Jobs\LoanRequestTimeOutJob;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;
use MathPHP\Finance;

/**
 * Class UserLoanRequest
 * Description:用户授信申请模型
 * Author: Sam
 * DateTime: 2019/1/2 10:23
 *
 * @package App\Models
 * @property int $id
 * @property int $user_id 用户id
 * @property int $loan_money 借款金额 单位分
 * @property int $period 借款周期
 * @property string $use 用途
 * @property int $cert_ocr_id 用户身份证信息id
 * @property int $cash_card_choice_id 用户储蓄卡id
 * @property int $credit_card_choice_id 用户信用卡id
 * @property int $user_face_log_id 用户face++验证id
 * @property int $user_base_info_id 用户基础信息id
 * @property int $user_phone_service_id 用户手机认证id
 * @property int $zhima_id 用户芝麻信用认证id
 * @property int $status 申请状态：1申请中 2成功 3失败 4待申请
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property string $trans_id 借款申请流水号
 * @property int $credit_id 授信id
 * @property int $pre_insurance_amt 前置险金额
 * @property int $actually_period 实际期数
 * @property int $actually_loan_money 实际金额
 * @property string $channel 渠道号
 * @property string|null $credit_time 授信时间
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest query()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereActuallyLoanMoney($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereActuallyPeriod($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCashCardChoiceId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCertOcrId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereChannel($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCreditCardChoiceId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCreditId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCreditTime($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereLoanMoney($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest wherePeriod($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest wherePreInsuranceAmt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereTransId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUpdatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUse($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUserBaseInfoId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUserFaceLogId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUserId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUserPhoneServiceId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereZhimaId($value)
 * @mixin \Eloquent
 * @property int $change_card_choice_id 换卡记录id
 * @property int $out_trade_id 新流返回的借款id
 * @property-read \App\Models\UserInfo $baseInfo
 * @property-read \App\Models\UserPhoneService $phone
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest byStatus($status)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest byUid($uid)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereChangeCardChoiceId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereOutTradeId($value)
 * @property-read \App\Models\UserCertOcr $userCert
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\UserAuthSpiderTransLog[] $userTransLog
 * @property string|null $failed_reason 授信失败原因
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\UserBankCard[] $bankCard
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\UserAuthStepEventLog[] $recentStepLog
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\UserAuthStepEventLog[] $stepLog
 * @property-read \App\Models\User $user
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereFailedReason($value)
 * @property string|null $apply_time 申请授信时间
 * @property string|null $failed_time 申请授信失败时间
 * @property-read \App\Models\UserBankCard $cashCard
 * @property-read \App\Models\UserBankCard $creditCard
 * @property-read \App\Models\LoanApply $loanApply
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereApplyTime($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereFailedTime($value)
 * @property int $current 用户当前授信记录
 * @property-read \App\Models\UserDeviceInfo $device
 * @property-read int $history_count
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereCurrent($value)
 * @property int|null $user_status 记录生成时用户的状态 1=新用户 2=老用户
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereUserStatus($value)
 * @property int $risk_status 风控状态 0=初始状态 1=通过 2=拒绝 3=继续 4=处理中 5=数据不全 6=风控错误
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereRiskStatus($value)
 * @property string|null $source 订单渠道
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereSource($value)
 * @property int $data_sign 0:新数据 1:旧数据
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\UserLoanRequest whereDataSign($value)
 */
class UserLoanRequest extends Model
{

    /**
     * 当前授信记录
     */
    CONST CURRENT_NOW = 1;
    /**
     * 以往授信记录
     */
    CONST CURRENT_BEFORE = 0;
    /**
     * 状态：未完成
     */
    CONST STATUS_CANCEL = 99;

    /**
     * 生成授信记录但未进行认证
     */
    CONST STATUS_NOT_VALID = 0;

    /**
     * 状态：待申请
     */
    CONST STATUS_UN_APPLY = 1;

    /**
     * 状态:申请中(进入轮询)
     */
    CONST STATUS_APPLY = 2;

    /**
     * 状态：轮询授信结果成功
     */
    CONST STATUS_SUCCESS = 3;

    /**
     * 状态：轮询授信结果失败
     */
    CONST STATUS_FAILD = 4;

    /**
     * 状态：收款超时
     */
    CONST STATUS_TIME_OUT = 5;

    /**
     * 状态：完全超时
     */
    CONST STATS_RESTART = 6;

    /**
     * 风控失败
     */
    CONST STATUS_RISK_FAILED = 7;

    /**
     * 风控拒绝
     */
    CONST STATUS_RISK_REJECT = 8;

    /**
     * 等待风控中
     */
    CONST STATUS_WAIT_FOR_RISK = 9;

    /**
     * 缺少信息
     */
    CONST STATUS_LACK_INFO = 10;

    /**
     * 用途：旅游
     */
    CONST USE_TRAVEL = '01';

    /**
     * 用途：教育
     */
    CONST USE_EDUCATION = '02';

    /**
     * 用途：婚庆
     */
    CONST USE_WEDDING = '03';

    /**
     * 用途：装修
     */
    CONST USE_DECORATE = '04';

    /**
     * 用途：家电
     */
    CONST USE_APPLIANCE = '05';

    /**
     * 用途：购车
     */
    CONST USE_CAR = '06';

    /**
     * 用途：日常百货
     */
    CONST USE_DAILY = '07';

    /**
     * 用途：消费
     */
    CONST USE_CONSUME = '08';

    /**
     * 授信号前缀
     * */
    CONST CREDIT_NO_PREFIX = 'KSKD_';

    /**
     * 爬虫类型
     * */
    CONST TYPE_CARRIER = 1,TYPE_TAOBAO = 2;

    /**
     * 设备类型
     * */
    CONST DEVICE_TYPE_WEB = 1, DEVICE_TYPE_AND = 2, DEVICE_TYPE_IOS = 3;

    /**
     * 不需要重试
     */
    const RETRY_NO = 0;

    /**
     * 需要重试
     */
    const RETRY_YES = 1;

    /**
     * 已经重试
     */
    const RETRY_ED = 2;

    /**
     * 重试不需要自动放款
     */
    const AUTO_LOAN_APPLY_NO = 0;

    /**
     * 重试需要自动放款
     */
    const AUTO_LOAN_APPLY_YES = 1;

    /**
     * 重试自动放款之前已重新授信
     */
    const AUTO_LOAN_APPLY_REQUEST = 2;

    /**
     * 重试已自动放款
     */
    const AUTO_LOAN_APPLY_SUCCESS = 3;

    /**
     * 枚举请求爬虫类型
     * */
    static $TYPE = array(
        self::TYPE_CARRIER => 'carrier',
        //todo 改为ali
        self::TYPE_TAOBAO => 'alipay'
    );

    /**
     * 枚举设备类型
     * */
    static $DEVICE_TYPE = array(
        self::DEVICE_TYPE_WEB => 'xincheng_web',
        self::DEVICE_TYPE_AND => 'xincheng_and',
        self::DEVICE_TYPE_IOS => 'xincheng_ios'
    );
    /**
     * 全局状态与授信状态的映射关系
     * @var array
     */
    public static $global_relation = [
        UserGlobal::STATUS_LOAN_REQUEST=>self::STATUS_APPLY,
        UserGlobal::STATUS_LOAN_REQUEST_SUCCESS=>self::STATUS_SUCCESS,
        UserGlobal::STATUS_LOAN_REQUEST_FAILED=>[self::STATUS_FAILD,self::STATUS_RISK_FAILED,self::STATUS_RISK_REJECT,self::STATUS_LACK_INFO],
    ];

    public static $record_status = [
        /**
         * 审批中
         */
        self::STATUS_WAIT_FOR_RISK,
        self::STATUS_APPLY,
        /**
         * 拒绝
         */
        self::STATUS_RISK_REJECT,
        self::STATUS_RISK_FAILED,
        self::STATUS_FAILD,
        /**
         * 成功
         */
        self::STATS_RESTART,
        self::STATUS_TIME_OUT,
        self::STATUS_SUCCESS,
        self::STATS_RESTART,
        self::STATUS_TIME_OUT,
    ];

    /**
     * 定义不可批量填充字段
     * @var array
     */
    protected $guarded = [
        'id',
    ];


    public function scopeByStatus($query, $status)
    {
        /**
         * @var $query Builder
         */
        return $query->where('status', $status);
    }

    public function scopeByUid($query, $uid)
    {
        /**
         * @var $query Builder
         */
        return $query->where('user_id', $uid);
    }

    public function phone()
    {
        return $this->hasOne(UserPhoneService::class,'id','user_phone_service_id');
    }

    /**
     * 银行卡关联
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     * @author luwei
     * @date 2019-01-10 21:29
     */
    public function bankCard(){
        return $this->hasOne(UserBankCard::class, 'id', 'cash_card_choice_id');
    }

    /**
     * 信用卡关联
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     * @author luwei
     * @date 2019-01-10 21:29
     */
    public function creditCard(){
        return $this->hasOne(UserBankCard::class, 'id', 'credit_card_choice_id');
    }

    public function baseInfo(){
        return $this->hasOne(UserInfo::class, 'id', 'user_base_info_id');
    }

    public function userCert(){
        return $this->hasOne(UserCertOcr::class, 'id', 'cert_ocr_id');
    }

    public function userTransLog(){
        return $this->hasMany(UserAuthSpiderTransLog::class, 'loan_request_id', 'id');
    }

    /**
     * 用户全局状态
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     * @author luwei
     * @date 2019-02-26 18:04
     */
    public function userGlobalStatus(){
        return $this->hasOne(UserGlobal::class, 'uid','user_id');
    }

    /**
     * 最新的步骤关联
     * @return mixed
     * @author luwei
     * @date 2019-01-07 10:41
     */
    public function recentStepLog(){
        return $this->hasMany(UserAuthStepEventLog::class,'loan_request_id','id')->orderBy('id','desc');
    }

    public function stepLog(){
        return $this->hasMany(UserAuthStepEventLog::class,'loan_request_id','id');
    }

    public function user(){
        return $this->belongsTo(User::class,'user_id','id');
    }

    /**
     * 设备信息关联
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     * @author luwei
     * @date 2019-01-13 21:24
     */
    public function device(){
        return $this->hasOne(UserDeviceInfo::class, 'loan_request_id','id');
    }

    /**
     * 放款关联
     * @author luwei
     * @date 2019-01-10 20:59
     */
    public function loanApply(){
        return $this->hasOne(LoanApply::class,'loan_request_id', 'id');
    }

    /**
     * Description:请求授信结果查询接口
     * Author: Sam
     * DateTime: 2019/1/16 18:27
     * @param $loan
     * @return bool
     * @throws \App\Exceptions\GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function getResult($loan)
    {
        $res = MoneyPlatformRequestFacade::getLoanApplyStatus($loan->credit_id);
        event(new NewFlowOrderEvent(NewFlowEnum::NewFlowLoanAuthorizeResult, $loan, 0, $res));
        if($res['code']=='01'){
            $status = $res['data']['status'];
            if($status==='S'){
                DB::beginTransaction();
                try{
                    $rate = SettingRepayRate::getRateByChannl($res['data']['channel'],$res['data']['period'])['insurance_rate'];
                    $pre_insurance_amt = round($res['data']['amount']*100*$rate);
                    $loan->credit_time = $res['data']['creditTime'];
                    $loan->channel = $res['data']['channel'];
                    $loan->actually_period = $res['data']['period'];
                    $loan->actually_loan_money = $res['data']['amount']*100;
                    $loan->pre_insurance_amt = $pre_insurance_amt;
                    $loan->status = self::STATUS_SUCCESS;
                    $loan->save();
                    DB::commit();
                    // 重试放款之前的重试授信不需要发短信和推送
                    if($loan->auto_loan_apply == UserLoanRequest::AUTO_LOAN_APPLY_NO){
                        //审核通过极光推送
                        $jpush_id = UserGlobal::where('uid',$loan->user_id)->value('jpush_registration_id');
                        SamLogFacade::debug("授信记录【{$loan->id}】审核通过查找jpush_registration_id结果:".json_encode($jpush_id));
                        if($jpush_id){
                            $push_data = [
                                'body'=>"您的{$loan->actually_period}期{$res['data']['amount']}元的借款申请已通过，请打开APP进行要款操作。",
                                'title'=>"借款申请审批通过",
                                'audience'=>JpushCode::AUDIENCE_TYPE_TWO,
                                'to'=>[
                                    $jpush_id,
                                ],
                                'extras'=>[
                                    'jump_type'=>1,
                                ],
                            ];
                            event(new JpushNoticeEvent($push_data));
                        }
                        $user = User::find($loan->user_id);
                        //发短信
                        if ($user->valid && SmsTemplate::TEMPLATE_NOTICE_PASS_RISK) {
                            SmsTemplate::send(SmsTemplate::TEMPLATE_NOTICE_PASS_RISK, $user->phone_num, ['name' => $user->valid->name]);
                        }
                        SamLogFacade::debug("授信申请【{$loan->id}】授信结果成功");
                        $delay_time = SettingLoan::getReceiptTime();
                        //普通超时的延迟队列
                        LoanRequestTimeOutJob::dispatch($loan)->delay(now()->addDays($delay_time['receipt_time_one']))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_TIME_OUT);
                        //授信成功6小时后的延迟队列
                        LoanRequestSuccessAfterSixJob::dispatch($loan)->delay(now()->addHours(6))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_SUCCESS_AFTER_SIX);
                        //授信成功24小时之后的延迟队列
                        LoanRequestSuccessAfterTwentyFourJob::dispatch($loan)->delay(now()->addHours(24))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_SUCCESS_AFTER_TWENTY_FOUR);
                        //授信还剩下12小时之后的延迟队列
                        LoanRequestSuccessRestTwelveJob::dispatch($loan)->delay(now()->addHours($delay_time['receipt_time_one']*24-12))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_SUCCESS_REST_TWELVE);
                    }
                }
                catch(Exception $exception)
                {
                    SamLogFacade::debug("授信记录【{$loan->id}】更改成功状态失败");
                    DB::rollBack();
                    return false;
                }
            }elseif($status[0]==='F'){
                SamLogFacade::debug("用户{$loan->user_id}授信申请【{$loan->id}】授信结果失败:".json_encode($res,JSON_UNESCAPED_UNICODE));
                if(in_array($res['subCode'],['F1008', 'F1999'])){
                    // 2019-04-10 F1007 审批失败
                    SamLogFacade::debug("授信记录【{$loan->id}】查询结果返回特殊失败状态：".json_encode($res,JSON_UNESCAPED_UNICODE));

                    event(new LoanRequestRetryEvent($loan));

                }else{
                    DB::beginTransaction();
                    try{
                        $loan->status = self::STATUS_FAILD;
                        $loan->failed_reason = $res['data']['message'];
                        SamLogFacade::debug("F1007--授信记录({$loan->id})查询结果返回特殊失败状态：".json_encode($res,JSON_UNESCAPED_UNICODE));

                        if($res['subCode'] == 'F1007'){
                            $loan->failed_reason = 'F1007';
                        }
                        $loan->failed_time = Carbon::now();
                        $loan->save();
                        DB::commit();
                        //审核通过极光推送
                        $jpush_id = UserGlobal::where('uid',$loan->user_id)->value('jpush_registration_id');
                        SamLogFacade::debug("授信记录【{$loan->id}】审核失败查找jpush_registration_id结果:".json_encode($jpush_id));
                        if($jpush_id){
                            $push_data = [
                                'body'=>"抱歉，您的借款申请未能通过审批，点击了解详细信息",
                                'title'=>"借款申请审批拒绝",
                                'audience'=>JpushCode::AUDIENCE_TYPE_TWO,
                                'to'=>[
                                    $jpush_id,
                                ],
                                'extras'=>[
                                    'jump_type'=>1,
                                ],
                            ];
                            event(new JpushNoticeEvent($push_data));
                        }
                        SamLogFacade::debug("用户{$loan->user_id}授信申请【{$loan->id}】授信结果失败");
                    }catch (Exception $exception){
                        SamLogFacade::debug("授信记录【{$loan->id}】更改失败状态失败");
                        DB::rollBack();
                        return false;
                    }
                }
            }
            return true;
        }else{
            SamLogFacade::debug("查询授信【{$loan->id}】结果状态码：【{$res['code']}】".PHP_EOL."查询授信结果错误信息：{$res['message']}");
            return false;
        }
    }

    /**
     * Description: 再次人脸识别
     * Author: Sam
     * DateTime: 2019-01-30 18:00
     * @param $loan
     * @throws \App\Exceptions\GeneralException
     * @throws \MathPHP\Exception\BadParameterException
     * @throws \ReflectionException
     */
    public static function againNotice($loan){
        //审核通过极光推送
        /**
         * @var $loan UserLoanRequest
         */
        $actually_money = $loan->actually_loan_money/100;
        $jpush_id = UserGlobal::where('uid',$loan->user_id)->value('jpush_registration_id');
        SamLogFacade::debug("授信记录【{$loan->id}】重新通过查找jpush_registration_id结果:".json_encode($jpush_id));
        if($jpush_id){
            $push_data = [
                'body'=>"您的{$loan->actually_period}期{$actually_money}元的借款申请已通过，请打开APP进行要款操作。",
                'title'=>"借款申请审批通过",
                'audience'=>JpushCode::AUDIENCE_TYPE_TWO,
                'to'=>[
                    $jpush_id,
                ],
                'extras'=>[
                    'jump_type'=>1,
                ],
            ];
            event(new JpushNoticeEvent($push_data));
        }
        $user = User::find($loan->user_id);
        //发短信
        if ($user->valid && SmsTemplate::TEMPLATE_NOTICE_PASS_RISK) {
            SmsTemplate::send(SmsTemplate::TEMPLATE_NOTICE_PASS_RISK, $user->phone_num, ['name' => $user->valid->name]);
        }
        $delay_time = SettingLoan::getReceiptTime();
        LoanRequestTimeOutJob::dispatch($loan)->delay(now()->addDays($delay_time['receipt_time_one']))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_TIME_OUT);
        LoanRequestSuccessAfterSixJob::dispatch($loan)->delay(now()->addHours(6))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_SUCCESS_AFTER_SIX);
        LoanRequestSuccessAfterTwentyFourJob::dispatch($loan)->delay(now()->addHours(24))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_SUCCESS_AFTER_TWENTY_FOUR);
        LoanRequestSuccessRestTwelveJob::dispatch($loan)->delay(now()->addHours($delay_time['receipt_time_one']*24-12))->onQueue(QueueKey::QUEUE_LOAN_REQUEST_SUCCESS_REST_TWELVE);
    }

    /**
     * 获取对应资源信息
     * @param $loan
     * @return array
     * @author luwei
     * @date 2019-01-10 20:57
     */
    public static function getResource($loan) {
        $info = [
            'id'         => $loan->id,
            'user_id'    => $loan->user_id,
            'status'     => $loan->status,
            'name'       => optional($loan->userCert)->name,
            'trade_id'   => $loan->trans_id,
            'card_num'   => optional($loan->userCert)->num,
            'valid_at'   => optional($loan->userCert)->valid_date_begin . '至' . optional($loan->userCert)->valid_date_end,
            'apply_time' => $loan->apply_time,
        ];
        return $info;
    }

    /**
     * Description:授信申请与银行卡一对一
     * Author: Sam
     * DateTime: 2019/1/12 20:23
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function cashCard()
    {
        return $this->hasOne(UserBankCard::class,'id','cash_card_choice_id');
    }


    /**
     * Description:每期还款金额与前置保费试算
     * Author: Sam
     * DateTime: 2019/1/12 21:31
     * @param $params
     * @return array
     * @throws \App\Exceptions\GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function getCalculate($params)
    {
        //通过渠道号获取利率
        $rate = SettingRepayRate::getRateByChannl($params['channel'],$params['period']);
        //计算总费用
        $calculate_platform = RepaySummary::trial($params['applyAmount'],$rate,1,$params['period']);
        $platform_total = array_values($calculate_platform);
        $platform_total = array_sum($platform_total);
        //计算资方费用
        $calculate = MoneyPlatformRequestFacade::applyLoanCalculate($params);
//        $total = $platform_total+$calculate['data']['plan'][0]['totalAmount'];
        $total = $platform_total+$calculate['data']['plan'][0]['principalAmount'];
//        $total = $platform_total;
        $total = floor($total*100)/100;
        //通过平台前置保费率计算前置保费
        $insurance = floor($params['applyAmount'] * 100 * $rate['insurance_rate'])/100;
//        $insurance_total = $insurance + $calculate['data']['preInsuranceAmount'];
        //保证险
        $insure = floor($params['applyAmount'] * $rate['insure_rate']*100)/100;
        $insurance_total = $insurance + $insure;//只算平台的前置险 + 保证险
        $data = [
            'total_amount'=>$total,
            'pre_insurance'=>$insurance_total,
        ];
        return $data;
    }

    /**
     * Description:获取剩余天数
     * Author: Sam
     * DateTime: 2019/1/13 10:56
     * @param $credit_time
     * @return array
     */
    public static function getRestDays($credit_time)
    {
        $receipt = SettingLoan::getReceiptTime();
        $total_day = $receipt['receipt_time_one'];
        $begin_time = Carbon::parse($credit_time);
        $end_time = $begin_time->addDays($total_day);
        $hours = Carbon::now()->diffInHours($end_time);
        $days = [
            'total_day'=>$total_day,
            'rest_day'=>ceil($hours/24),
        ];
        return $days;
    }

    /**
     * Description:获取历史借次
     * Author: Sam
     * DateTime: 2019/1/15 15:18
     * @return int
     */
    public function getHistoryCountAttribute()
    {
        $count = LoanApply::where('user_id',$this->attributes['user_id'])
            ->whereNotNull('loan_time')
            ->where('loan_time','<',"{$this->attributes['apply_time']}")
            ->count();
        $has_one = LoanApply::where('loan_request_id',$this->attributes['id'])->first();
        if($has_one){
            $count++;
        }
        return $count;
    }

    /**
     * model by trans_id
     * @param $query
     * @param $transId
     * @return mixed
     * @author luwei
     * @date 2019-02-26 11:58
     */
    public function scopeByTransId($query, $transId){
        return $query->where('trans_id',$transId);
    }

    public function getActualMoneyAttribute(){
        return $this->attributes['actually_loan_money']/100;
    }
    public static function makeRecord($loans){
        $res = [];
        foreach ($loans as $key => $loan){
            /**
             * @var UserLoanRequest $loan
             */
            $status = $loan->status;
            $unit = [
                'loan_id'=>$loan->id,
                'loan_time'=>$loan->apply_time,
                'pay_order_number'=>null,
                'repay_id'=>null,
            ];
            if(in_array($status,[self::STATUS_SUCCESS,self::STATUS_TIME_OUT,self::STATS_RESTART])){ //授信成功
                $loan_status = LoanApply::getStatusByLoanRequestId($loan->id);
                if(in_array($loan_status,[LoanApply::LOAN_STATUS_SUCCESS,LoanApply::LOAN_HANDLE_CHANGE_CARD_SUCCESS])){
                    //放款成功，待还款
                    $repay_info = RepaySummary::getSingleFrontRepayInfo($loan->id);
                    $unit['period_count'] = $loan->actually_period;
                    $unit['amount'] = $repay_info['amount'];
                    $unit['type'] = self::$repay_status_relation[$repay_info['type']];
                    $unit['repay_amount'] = $repay_info['repay_amount'];
//                    $unit['fines_amount'] = $repay_info['fines_amount'];
                    $unit['fines_amount'] = 0;
                    $unit['overdue_day'] = $repay_info['overdue_day'];
                    $unit['pay_order_number'] = $repay_info['pay_order_number'];
                    $unit['repay_id'] = $repay_info['id'];
                    $unit['period'] = $repay_info['period'];

                }elseif(in_array($loan_status,[LoanApply::LOAN_STATUS_FAIL,LoanApply::LOAN_HANDLE_CHANGE_CARD_FAIL])){
                    //放款失败
                    $unit['period_count'] = $loan->actually_period;
                    $unit['amount'] = $loan->actually_loan_money/100;
                    $unit['type'] = self::LOAN_STATUS_LOAN_FAIL;
                    $unit['repay_amount'] = self::getCalculate(['applyAmount'=>$loan->actually_loan_money/100,'period'=>$loan->actually_period,'channel'=>$loan->channel])['total_amount'];
                    $unit['fines_amount'] = 0;
                    $unit['overdue_day'] = 0;
                    $unit['period'] = 1;
                }elseif(in_array($loan_status,[LoanApply::LOAN_STATUS_PROCESSING,LoanApply::LOAN_CHANGE_CARD_HANDLING])){
                    //待收款
                    $unit['period_count'] = $loan->actually_period;
                    $unit['amount'] = $loan->actually_loan_money/100;
                    $unit['type'] = self::LOAN_STATUS_LOANING;
                    $unit['repay_amount'] = self::getCalculate(['applyAmount'=>$loan->actually_loan_money/100,'period'=>$loan->actually_period,'channel'=>$loan->channel])['total_amount'];
                    $unit['fines_amount'] = 0;
                    $unit['overdue_day'] = 0;
                    $unit['period'] = 1;
                }elseif($loan_status == LoanApply::LOAN_CHANGE_CARD){
                    //收款失败
                    $unit['period_count'] = $loan->actually_period;
                    $unit['amount'] = $loan->actually_loan_money/100;
                    $unit['type'] = self::LOAN_STATUS_LOAN_ERROR;
                    $unit['repay_amount'] = self::getCalculate(['applyAmount'=>$loan->actually_loan_money/100,'period'=>$loan->actually_period,'channel'=>$loan->channel])['total_amount'];
                    $unit['fines_amount'] = 0;
                    $unit['overdue_day'] = 0;
                    $unit['period'] = 1;
                }else{
                    $unit['period_count'] = $loan->actually_period;
                    $unit['amount'] = $loan->actually_loan_money/100;
                    $unit['type'] = self::LOAN_STATUS_PEND_SUCCESS;
                    $unit['repay_amount'] = self::getCalculate(['applyAmount'=>$loan->actually_loan_money/100,'period'=>$loan->actually_period,'channel'=>$loan->channel])['total_amount'];
                    $unit['fines_amount'] = 0;
                    $unit['overdue_day'] = 0;
                    $unit['period'] = 1;
                }
            }elseif(in_array($status,[self::STATUS_RISK_REJECT,self::STATUS_RISK_FAILED,self::STATUS_FAILD])){
                //审批失败
                $loan_money = !empty($loan->actually_loan_money)?$loan->actually_loan_money:$loan->loan_money;
                $unit['period_count'] = $loan->period;
                $unit['amount'] = $loan_money/100;
                $unit['type'] = self::LOAN_STATUS_PEND_FAIL;
                $unit['repay_amount'] = self::trial(0.34,1,$loan->period,$loan_money/100);
                $unit['fines_amount'] = 0;
                $unit['overdue_day'] = 0;
                $unit['period'] = 1;
            }else{
                //审批中
                $unit['period_count'] = $loan->period;
                $unit['amount'] = $loan->loan_money/100;
                $unit['type'] = self::LOAN_STATUS_PENDING;
                $unit['repay_amount'] = self::trial(0.34,1,$loan->period,$loan->loan_money/100);
                $unit['fines_amount'] = 0;
                $unit['overdue_day'] = 0;
                $unit['period'] = 1;
            }
            $res[] = $unit;
        }
        return $res;
    }

    /**
     * 借款记录审批中
     */
    const  LOAN_STATUS_PENDING = 0;

    /**
     * 借款记录待放款（授信成功）
     */
    const LOAN_STATUS_PEND_SUCCESS = 1;

    /**
     * 借款记录审批失败
     */
    const LOAN_STATUS_PEND_FAIL = 2;

    /**
     * 借款记录待收款（放款中）
     */
    const LOAN_STATUS_LOANING = 3;

    /**
     * 借款记录放款失败
     */
    const LOAN_STATUS_LOAN_FAIL = 4;

    /**
     * 借款记录收款失败 (需要换卡)
     */
    const LOAN_STATUS_LOAN_ERROR = 5;

    /**
     * 借款记录待还
     */
    const LOAN_STATUS_REPAY_READY = 6;

    /**
     * 借款记录逾期
     */
    const LOAN_STATUS_REPAY_DELAY = 7;

    /**
     * 借款记录已还
     */
    const LOAN_STATUS_ALREADY_REPAY = 8;

    /**
     * 借款记录还清
     */
    const LOAN_STATUS_ALL_REPAY = 9;

    /**
     * @var array 还款状态对应借款记录状态
     */
    public static $repay_status_relation = [
        1=>self::LOAN_STATUS_REPAY_READY,
        2=>self::LOAN_STATUS_REPAY_DELAY,
        3=>self::LOAN_STATUS_ALREADY_REPAY,
        5=>self::LOAN_STATUS_ALL_REPAY,
    ];

    /**
     * Description:公式试算
     * Author: Sam
     * DateTime: 2019-03-01 19:06
     * @param $rate "利率"
     * @param $current "当前期数"
     * @param $period "总期数"
     * @param $amount "总金额"
     * @return string
     */
    public static function trial($rate,$current,$period,$amount){
        $ppmt = Finance::ppmt($rate/12,$current,$period,$amount);
        $ipmt = Finance::ipmt($rate/12,$current,$period,$amount);
        $total = abs(bcadd($ppmt,$ipmt,2));
        return $total;
    }

    public function checkApplyAble(){
        $array = ['user_face_log_id','user_base_info_id','cert_ocr_id','cash_card_choice_id','credit_card_choice_id','user_phone_service_id','zhima_id'];
        $flag = 1;
        foreach ($array as $v){
            if(empty($this->attributes[$v])){
                $flag = 0;
                break;
            }
        }
        return $flag;
    }
}
